package com.acme.bankapp.network;

import com.acme.bankapp.domain.Client;
import com.acme.bankapp.exceptions.QueueClosedException;
import com.acme.bankapp.service.Queue;

public class EmailService {
	private static final String EMAIL_WORKER_SIGNATURE = "\n--- [Email Worker] ";
	Queue<Email> emailQueue;

	/**
	 * Observes email send queue and sends emails.
	 * @param emailQueue
	 */
	public EmailService(Queue<Email> emailQueue) {
		this.emailQueue = emailQueue;		
		(new Thread() {
			@Override
			public void run() {
				Email email;
				while (true) {
					if ((EmailService.this.emailQueue.isClosed())
							&&(EmailService.this.emailQueue.isEmpty())) {
						System.out.println(EMAIL_WORKER_SIGNATURE + "Terminating.\n");
						break;
					} else {
						email = null;
						try {
							email = EmailService.this.emailQueue.pop();
							System.out.println(EMAIL_WORKER_SIGNATURE + email + " has been sent.\n");							
						} catch (InterruptedException e) {
							if (email != null) {
								System.out.println(EMAIL_WORKER_SIGNATURE + email + " has been sent.\n");							
							} else {
								System.out.println(EMAIL_WORKER_SIGNATURE + "Something gone wrong!");
							}
						} 					
					}
				}
			}
		}).start(); 
	}

	/**
	 * Observes email send queue and sends emails.
	 * Spinlock implementation.
	 * (exists only to match labguide reqs, hence has emailQueue hardcoded)
	 * @param emailQueue
	 */
	public EmailService() {
		emailQueue = new Queue<Email>();		
		(new Thread() {
			@Override
			public void run() {
				Email email;
				while (true) {
					email = EmailService.this.emailQueue.hardPop();
					if (email != null) {
						System.out.println(EMAIL_WORKER_SIGNATURE + email + " has been sent.\n");
					} else if (EmailService.this.emailQueue.isClosed()) {
						System.out.println(EMAIL_WORKER_SIGNATURE + "Terminating.\n");
						break;
					} else {
						try {
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							System.out.println(EMAIL_WORKER_SIGNATURE + "Who wakes me?!");
						}
					}
				}
			}
		}).start(); 
	}

	public void close() {
		emailQueue.close();
	}

	/**
	 * Adds email with client info and address to send queue.
	 * @param client
	 * @param address
	 * @return
	 */
	public void sendNotificationEmail(Client client, String address) {
		try {
			emailQueue.add(new Email(client, address));
		} catch (QueueClosedException e) {
			System.out.println(EMAIL_WORKER_SIGNATURE + "Send queue is closed. Email will not be sent.\n");
		}
	}


}
